using System.Collections.Generic;
using UnityEngine;

namespace Gameplay.PVE
{
    public class PveMapController : MonoBehaviour
    {
        public GameObject buildingRoot;
        public GameObject roadRoot;
        public GameObject groundRoot;
        public GameObject sundriesRoot;
        public GameObject lightRoot;
        public List<GameObject> lights;

        public class MapObjData
        {
            public int index;
            public GameObject gameObject;
            public List<GameObject> subObjects;
            public List<Vector3> subObjectPositions;
            public List<Vector3> subObjectForwards;
            public List<Vector3> subObjectScales;
            public Vector3 position;
        }

        private Dictionary<int, MapObjData> mapDic;

        public List<GameObject> GetLights()
        {
            return lights;
        }
        
        public Dictionary<int, MapObjData> GetMapDic()
        {
            mapDic = new Dictionary<int, MapObjData>();
            for (int i = 0; i < roadRoot.transform.childCount; i++)
            {
                var road = roadRoot.transform.GetChild(i);
                int index;
                int.TryParse(road.name, out index);
                if (!mapDic.ContainsKey(index))
                {
                    MapObjData data = new MapObjData
                    {
                        index = index,
                        gameObject = road.gameObject,
                        subObjects = new List<GameObject>(),
                        subObjectPositions = new List<Vector3>(),
                        subObjectForwards = new List<Vector3>(),
                        subObjectScales = new List<Vector3>(),
                    };
                    mapDic.Add(index,data);
                }
            }

            //for (int i = 0; i < buildingRoot.transform.childCount; i++)
            //{
                //var child = buildingRoot.transform.GetChild(i);
                /*var meshs = buildingRoot.GetComponentsInChildren<MeshFilter>();
                for (int j = 0; j < meshs.Length; j++)
                {
                    AddObjectToMap(meshs[j].gameObject.transform);
                }*/
                /*for (int j = 0; j < child.childCount; j++)
                {
                    var subChild = child.GetChild(j);
                    subChild
                    //Debug.LogError(subChild.name + " " + subChild.childCount);
                    //subChild.SetParent(null);
                    //AddObjectToMap(subChild);
                }*/
            //}
            AddObjectToMapFromMesh(buildingRoot.transform);
            AddObjectToMapFromParent(groundRoot.transform);
            //AddObjectToMapFromParent(lightRoot.transform);
            AddObjectToMapFromMesh(sundriesRoot.transform);
            return mapDic;
        }

        private void AddObjectToMapFromParent(Transform root)
        {
            for (int i = 0; i < root.childCount; i++)
            {
                AddObjectToMap(root.GetChild(i));
            }
        }

        private void AddObjectToMapFromMesh(Transform root)
        {
            var meshs = root.GetComponentsInChildren<MeshFilter>();
            for (int j = 0; j < meshs.Length; j++)
            {
                AddObjectToMap(meshs[j].gameObject.transform);
            }
        }
        
        private void AddObjectToMap(Transform obj)
        {
            //for (int i = 0; i < root.childCount; i++)
            {
                //var obj = root.GetChild(i);
                float distance = float.MaxValue;
                int targetMapIndex = -1;
                Vector3 position = obj.position;
                foreach (var item in mapDic.Values)
                {
                    float d = Vector3.Distance(item.gameObject.transform.position, position);
                    if (d < distance)
                    {
                        targetMapIndex = item.index;
                        distance = d;
                    }
                }
                
                MapObjData targetMapData;
                if (mapDic.TryGetValue(targetMapIndex, out targetMapData))
                {
                    targetMapData.subObjects.Add(obj.gameObject);
                    targetMapData.subObjectPositions.Add(obj.position - targetMapData.gameObject.transform.position);
                    targetMapData.subObjectForwards.Add(obj.forward);
                    targetMapData.subObjectScales.Add(obj.lossyScale);
                    targetMapData.position = targetMapData.gameObject.transform.position;
                }
            }
        }
    }
}